<!--
 * @Description: 花了还有无感结算页面
 * @Author: Kerwin
 * @Date: 2025-05-26 14:46:49
 * @LastEditTime: 2025-11-25 11:06:51
 * @LastEditors:  Please set LastEditors
-->
<template>
  <view class="physicalShopCheck">
    <!-- 加载状态 -->
    <view v-if="pageLoading" class="loading-mask">
      <u-loading mode="circle" size="60" color="#2979ff"></u-loading>
      <text class="loading-text">
        {{ wechatLoginConfig.isRetrying ? 
          `登录中... (${wechatLoginConfig.currentRetryCount + 1}/${wechatLoginConfig.maxRetryCount + 1})` : 
          '加载中...' }}
      </text>
      <text v-if="wechatLoginConfig.isRetrying" class="retry-tip">
        如持续失败，请检查网络连接，或在app里门店买单。
      </text>
    </view>

    <u-navbar
      :title-bold="false"
      v-if="!isWeChatBrowser"
      :is-back="false"
      color="#333"
      :background="{ backgroundColor: '#f9c9ae' }"
    >
      <template #right>
        <view style="margin: 0 20rpx" @click="clearUser">
          <u-icon name="man-delete" color="#999999" size="42"></u-icon>
        </view>
      </template>
    </u-navbar>
    <!-- 头部 -->
    <view class="topTitLe">
      <view class="leftTitle">
        <view style="font-weight: 700; font-size: 32rpx; margin-bottom: 20rpx"
          >消费总金额</view
        >
        <view style="color: #999">请询问金额后提交</view>
      </view>
      <view class="rightTitle">
        <u-image width="180rpx" height="150rpx" :src="moneyIcon"></u-image>
      </view>
    </view>
    <!-- 商户信息 -->
    <view class="shopBox">
      <text class="name"
        ><u-icon
          size="40"
          style="vertical-align: middle"
          :name="shopIcon1"
        ></u-icon>
        {{ shopInfo.name }}</text
      >
      <view class="inptBox">
        <u-input
          v-model="money"
          v-input-decimal2
          type="digit"
          inputmode="decimal"
          focus
          pattern="number"
          placeholder="¥ 0.00"
          input-align="center"
          :custom-style="{
            fontSize: '52rpx'
          }"
          :disabled="inptDisabled"
        />
        <text class="unit">(元)</text>
      </view>
      <view class="yt-list-cell shape2">
        <view class="cell-tit">
          抵用券抵扣：<text class="red"
            >（本次最多使用{{ scoreMax }}积分，可抵扣{{ scoreMax }}元）</text
          ></view
        >
        <view class="cell-tip">
          <view class="wallet"> 抵用券剩余：{{ userScore }}</view>
          <view class="right" style="width: 250rpx">
            <u-input
              class="inputBox"
              :disabled="!userScore"
              v-input-decimal
              placeholder="请输入抵扣积分"
              type="digit"
              v-model="scoreConsumption"
              @blur="onScoreChange"
              :border="true"
            />
          </view>
        </view>
        <view class="hjfScore"> 绿色积分剩余：{{ hjfUserScore }}</view>
      </view>

      <view
        class="radioBox"
        v-if="shopInfo.shopMoneyRules && shopInfo.shopMoneyRules.length > 1"
      >
        <u-radio-group
          v-model="moneyRuleId"
          @change="radioGroupChange"
          :wrap="true"
        >
          <u-radio
            v-for="(item, index) in shopInfo.shopMoneyRules"
            :key="index"
            :name="item.moneyRuleId"
          >
            {{ item.userMoneyRuleName }}
          </u-radio>
        </u-radio-group>
      </view>
    </view>
    <!-- 结算 -->
    <u-button
      :disabled="!shopInfo.shopId"
      class="hy-btn"
      type="primary"
      ripple
      @click="toPayment"
    >
      确认付款
    </u-button>
    <view class="hy-link" v-if="showBindPhone" @click="toBindPhone">
      绑定手机号
    </view>
  </view>
</template>

<script setup lang="ts">
import { computed, reactive, ref, watch, nextTick } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import { storeToRefs } from 'pinia'
import { useConfigStore, useUserStore } from '@/store'
import { enumAll, moneyApi, orderApi, productApi, userApi } from '@/api'
import { getQueryVariable, getQueryObject } from '@/utils/common'
import debounce from 'lodash/debounce'

// 图片
import moneyIcon from '@/static/hlhy/money2.png'
import shopIcon1 from '@/static/hlhy/shopIcon1.png'

// Store 数据
const configStore = useConfigStore()
const userStore = useUserStore()
const { isWeChatBrowser } = storeToRefs(configStore)
const { accessToken, useShareCode, userInfo } = storeToRefs(userStore)

// 响应式数据
const pageLoading = ref(false)
const inptDisabled = ref(false)
const money = ref('')
const scoreConsumption = ref(0)
const moneyRuleId = ref(null)

// 用户相关数据
const userPhone = ref('')
const showBindPhone = ref(false)
const loginSuccess = ref(false)

// 店铺和积分数据
const shopInfo = reactive({
  name: '',
  shopId: '',
  shopMoneyRules: []
})

const walletInfo = reactive({
  userScore: 0,
  hjfUserScore: 0,
  maxUserScore: 0
})

// 订单数据
const orderData = ref({
  remark: '',
  orderProductSkus: [] as any[],
  scoreMoney: 0
})

// 业务标志
const isHjfShop = ref(false)
const whiteList = ref(0)
const shopMode = ref()

// 微信登录相关配置
const wechatLoginConfig = reactive({
  maxRetryCount: 3,
  currentRetryCount: 0,
  retryDelay: 1000,
  isRetrying: false
})

// 计算属性
const scoreMax = computed(() => {
  if (!money.value) return 0
  
  let deductionAmount = 0
  if (isHjfShop.value) {
    const rate = whiteList.value ? 0.5 : getDeductionRate(moneyRuleId.value)
    deductionAmount = Number(money.value) * rate
  }
  
  const maxDeduction = Math.min(deductionAmount, walletInfo.maxUserScore)
  return Math.floor(maxDeduction * 10) / 10
})

// 方法
const getDeductionRate = (ruleId: any) => {
  if (enumAll.MoneyRuleGroups.GROUP_25.ruleIds.includes(ruleId)) {
    return enumAll.MoneyRuleGroups.GROUP_25.rate
  }
  if (enumAll.MoneyRuleGroups.GROUP_375.ruleIds.includes(ruleId)) {
    return enumAll.MoneyRuleGroups.GROUP_375.rate
  }
  return 0.5
}

const onScoreChange = () => {
  if (!money.value) {
    uni.showToast({ icon: 'none', title: '请先输入支付金额' })
    scoreConsumption.value = 0
    return
  }

  let validScore = Math.min(Math.max(0, scoreConsumption.value), scoreMax.value)
  if (scoreConsumption.value !== validScore) {
    uni.showToast({ icon: 'none', title: '积分有误' })
  }
  
  scoreConsumption.value = validScore
  walletInfo.userScore = Math.floor((walletInfo.maxUserScore - validScore) * 10) / 10
}

// 创建订单
const createOrder = debounce(async () => {
  try {
    const { data } = await orderApi.orderAdd(orderData.value)
    if (data) {
      location.href = `https://api.mylkjgs.com/?token=${accessToken.value}&orderId=${data.id}`
    }
  } catch (err) {
    console.log('创建订单失败:', err)
  }
  uni.hideLoading()
}, 500)

const toPayment = async () => {
  if (!money.value || Number(money.value) <= 0) {
    uni.showToast({
      icon: 'none',
      title: !money.value ? '请输入支付金额' : '最低金额需大于0元'
    })
    return
  }

  if (scoreConsumption.value > scoreMax.value) {
    uni.showToast({
      icon: 'none',
      title: `最多只能抵扣${scoreMax.value}元`
    })
    return
  }

  uni.showLoading({ title: '', mask: true })
  try {
    await prepareOrderData()
    createOrder()
  } catch (err) {
    uni.hideLoading()
  }
}

const prepareOrderData = async () => {
  const { data } = await productApi.getShopProductSkuList({
    detail: false,
    dynamicPrice: true,
    shopId: shopInfo.shopId
  })

  if (data.records?.[0]) {
    const productSku = data.records[0]
    orderData.value.orderProductSkus = [{
      count: 1,
      money: money.value,
      shopProductSkuId: productSku.id,
      moneyRuleId: moneyRuleId.value,
      dynamicPric: true
    }]

    // 添加分享信息
    const shareCode = uni.getStorageSync('shareCode')
    if (shareCode && useShareCode.value) {
      orderData.value.orderProductSkus[0].externalData = {
        userShareCode: shareCode
      }
    }

    // 设置积分抵扣
    if (scoreConsumption.value) {
      orderData.value.scoreMoney = scoreConsumption.value
    }
  }
}

// 用户信息相关
const getUserDetailInfo = async () => {
  try {
    const { data } = await userApi.userInfo()
    userPhone.value = data?.phone || ''
    showBindPhone.value = !userPhone.value
  } catch (error) {
    console.error('获取用户信息失败', error)
    userPhone.value = ''
    showBindPhone.value = true
  }
}

const updateUserMode = async () => {
  const hyType = shopMode.value == 3381 ? { name: '花了还有', id: 1 } :
                 shopMode.value == 3382 ? { name: '鑫复来', id: 4 } :
                 { name: '黑银', id: 0 }
  
  uni.setStorageSync('hyType', JSON.stringify(hyType))
  await userApi.userInfoUpdate({ mode: shopMode.value })
}

// 积分相关
const getWalletInfo = async (walletRuleId: number) => {
  const { data } = await moneyApi.walletInfo({ walletRuleId })
  const amount = Math.floor(data.money * (walletRuleId === 2013 ? 100 : 10)) / (walletRuleId === 2013 ? 100 : 10)
  
  if (walletRuleId === 2013) {
    walletInfo.hjfUserScore = amount
  } else {
    walletInfo.userScore = amount
    walletInfo.maxUserScore = amount
  }
}

// 店铺信息
const getShopInfo = async () => {
  try {
    const { data } = await productApi.getShopInfo({
      id: shopInfo.shopId,
      detail: true,
      otherColumns: 'moneyRuleDetails'
    })

    const { name, shopMoneyRules, code, user, integralsRuleId, specialStatus, shopMode: mode } = data
    
    shopInfo.name = name
    shopMode.value = mode
    whiteList.value = specialStatus

    // 存储店铺信息
    uni.setStorageSync('shopCode', code)
    uni.setStorageSync('shopOwnerShareCode', user.shareCode)

    // 处理积分店铺
    if (integralsRuleId == 1) {
      isHjfShop.value = true
      getWalletInfo(enumAll.wallet_rule_id_enum.花积分钱包)
      getWalletInfo(enumAll.wallet_rule_id_enum.绿色积分钱包)
    }

    // 处理金额规则
    if (shopMoneyRules?.length) {
      shopInfo.shopMoneyRules = shopMoneyRules
      if (!moneyRuleId.value || !shopMoneyRules.find((item: any) => item.moneyRuleId == moneyRuleId.value)) {
        moneyRuleId.value = shopMoneyRules[0].moneyRuleId
      }
    }
  } catch (error) {
    console.error('获取店铺信息失败:', error)
  }
}

// 金额变化处理
const handleMoneyChange = debounce((newValue: string) => {
  if (newValue) {
    nextTick(() => {
      money.value = newValue.replace(/^(-)*(\d+)\.(\d\d).*$/, '$1$2.$3')
    })
    
    if (Number(newValue) < 0) {
      uni.showToast({ icon: 'none', title: '金额不能小于0' })
      money.value = '0'
    } else {
      scoreConsumption.value = scoreMax.value
      walletInfo.userScore = Math.floor((walletInfo.maxUserScore - scoreMax.value) * 10) / 10
    }
  } else {
    walletInfo.userScore = Math.floor(walletInfo.maxUserScore * 10) / 10
  }
}, 300)

// 微信登录相关方法
const handleWeChatLogin = async (option: any) => {
  if (!wechatLoginConfig.isRetrying) {
    wechatLoginConfig.currentRetryCount = 0
    wechatLoginConfig.retryDelay = 1000
  }
  
  try {
    console.log(`微信登录尝试 ${wechatLoginConfig.currentRetryCount + 1}/${wechatLoginConfig.maxRetryCount}`)
    
    // 第一步：微信授权
    await userStore.wxAuth()
    const codeAuth = getQueryVariable('code')
    
    if (!codeAuth) {
      throw new Error('获取微信授权码失败，请检查是否在微信环境中')
    }
    
    // 第二步：微信登录
    await userStore.wxWebLogin(codeAuth)
    
    // 第三步：业务登录
    const result: any = await userStore.hlhyLoginByOpenId()
    
    if (!result.status) {
      throw new Error(result.message || '业务登录失败')
    }
    
    // 登录成功处理
    loginSuccess.value = true
    wechatLoginConfig.currentRetryCount = 0
    wechatLoginConfig.isRetrying = false
    
    // 异步获取用户信息
    setTimeout(() => {
      getUserDetailInfo()
      getShopInfo()
    }, 100)
    
    uni.showToast({
      title: '登录成功',
      icon: 'success',
      duration: 1500
    })
    
  } catch (error: any) {
    console.error(`微信登录失败 (尝试 ${wechatLoginConfig.currentRetryCount + 1}):`, error)
    
    // 重试逻辑
    if (wechatLoginConfig.currentRetryCount < wechatLoginConfig.maxRetryCount) {
      await handleRetry(option, error)
    } else {
      await handleFinalFailure(error)
    }
  } finally {
    if (!wechatLoginConfig.isRetrying) {
      pageLoading.value = false
    }
  }
}

// 处理重试
const handleRetry = async (option: any, error: any) => {
  wechatLoginConfig.currentRetryCount++
  wechatLoginConfig.isRetrying = true
  
  const retryMessage = `登录失败，${wechatLoginConfig.retryDelay/1000}秒后第${wechatLoginConfig.currentRetryCount}次重试`
  
  uni.showToast({
    title: retryMessage,
    icon: 'none',
    duration: 2000
  })
  
  // 指数退避策略：每次重试延迟时间增加
  wechatLoginConfig.retryDelay = Math.min(wechatLoginConfig.retryDelay * 1.5, 5000)
  
  await new Promise(resolve => setTimeout(resolve, wechatLoginConfig.retryDelay))
  
  // 继续重试
  handleWeChatLogin(option)
}

// 处理最终失败
const handleFinalFailure = async (error: any) => {
  wechatLoginConfig.isRetrying = false
  loginSuccess.value = false
  
  const errorMessage = getErrorMessage(error)
  
  uni.showModal({
    title: '登录失败',
    content: errorMessage,
    confirmText: '重新登录',
    cancelText: '清除缓存',
    showCancel: true,
    success: (res) => {
      if (res.confirm) {
        // 重置重试配置并重新登录
        wechatLoginConfig.currentRetryCount = 0
        wechatLoginConfig.retryDelay = 1000
        pageLoading.value = true
        handleWeChatLogin(getQueryObject(window.location.search))
      } else if (res.cancel) {
        clearUser()
      }
    }
  })
}

// 获取友好的错误信息
const getErrorMessage = (error: any) => {
  const message = error?.message || error?.errorDesc || '未知错误'
  
  if (message.includes('网络') || message.includes('请求失败')) {
    return '网络连接不稳定，请检查网络设置后重试'
  } else if (message.includes('授权')) {
    return '微信授权失败，请允许授权后继续使用'
  } else if (message.includes('code') || message.includes('授权码')) {
    return '获取微信授权码失败，请重新进入页面'
  } else {
    return `登录失败：${message}，请稍后重试`
  }
}

// 登录流程处理
const handleLoginProcess = async (option: any) => {
  try {
    if (userStore.hasLogin) {
      await getShopInfo()
      return
    }

    if (isWeChatBrowser.value) {
      pageLoading.value = true
      await handleWeChatLogin(option)
    } else {
      const tempParams = getQueryObject(window.location.search)
      uni.navigateTo({
        url: `/pages/login/index?&qrcode=${tempParams.qrcode}&shopId=${tempParams.shopId}&shareCode=${tempParams.shareCode}`
      })
    }
  } catch (error) {
    console.error('登录流程失败:', error)
    pageLoading.value = false
  }
}

// 页面初始化
const initPage = (option: any) => {
  const { shopId, moneyRuleId: ruleId, money: amount } = option || {}
  
  shopInfo.shopId = shopId || ''
  if (ruleId) moneyRuleId.value = ruleId
  if (amount) {
    money.value = amount
    inptDisabled.value = true
  }
}

// 事件处理
const toBindPhone = () => {
  uni.setStorageSync('currentUrl', window.location.href)
  uni.navigateTo({ url: '/pages/physicalShopCheck/bindPhone' })
}

const clearUser = () => {
  userStore.syncClearToken()
  userStore.syncClearUserInfo()
  const tempParams = getQueryObject(window.location.search)
  uni.navigateTo({
    url: `/pages/physicalShopCheck/hlhyPay?&qrcode=${tempParams.qrcode}&shopId=${tempParams.shopId}&shareCode=${tempParams.shareCode}`
  })
}

const radioGroupChange = (e: any) => {
  console.log('金额规则变更:', e)
}

// 监听器
watch(money, handleMoneyChange)

watch([accessToken, () => userStore.hasLogin], async ([newToken, hasLogin]) => {
  if (newToken && hasLogin && shopInfo.shopId) {
    await getShopInfo()
  }
})

watch(loginSuccess, (newStatus) => {
  if (newStatus) {
    getUserDetailInfo()
  } else {
    showBindPhone.value = false
  }
})

// 计算属性别名（为了模板兼容性）
const userScore = computed(() => walletInfo.userScore)
const hjfUserScore = computed(() => walletInfo.hjfUserScore)

// 生命周期
onLoad(async (option) => {
  initPage(option)
  setTimeout(() => handleLoginProcess(option), 0)
  
  if (userStore.hasLogin) {
    setTimeout(() => getUserDetailInfo(), 500)
  }
})
</script>

<style lang="scss" scoped>
.physicalShopCheck {
  padding: 30rpx;
  text-align: center;
  background: linear-gradient(#fab791 0%, rgba(255, 250, 224, 0) 30%);
  transform: translateZ(0);
  backface-visibility: hidden;
  perspective: 1000;

  .loading-mask {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(255, 255, 255, 0.9);
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    z-index: 9999;
    
    .loading-text {
      margin-top: 20rpx;
      color: #666;
      font-size: 28rpx;
    }
    
    .retry-tip {
      margin-top: 10rpx;
      color: #999;
      font-size: 24rpx;
    }
  }

  .topTitLe {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-top: 20rpx;

    .leftTitle {
      text-align: left;
    }

    .rightTitle {
      image {
        will-change: transform;
      }
    }
  }

  .shopBox {
    min-height: 300rpx;
    padding: 20rpx;
    background: url('@/static/pay1.png') no-repeat;
    background-size: 100% 100%;
    box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.1);

    .name {
      text-align: center;
      margin-top: 20rpx;
      font-size: 32rpx;
      font-weight: bold;
    }
  }

  .inptBox {
    display: flex;
    justify-content: center;
    align-items: flex-end;
    padding: 20rpx 0;
    border-top: 1px solid #8080802e;
    border-bottom: 1px solid #8080802e;
    position: relative;
    margin-top: 40rpx;
    font-size: 50rpx;

    .unit {
      right: 0;
      top: 36rpx;
      font-size: 28rpx;
      margin-bottom: 10rpx;
    }
  }

  .yt-list-cell {
    display: flex;
    align-items: center;
    padding: 40rpx 0;
    position: relative;

    .cell-tit {
      flex: 1;
      font-size: 26rpx;
      color: #909399;
      text-align: left;

      .red {
        color: #ff6c18;
      }
    }

    &.shape2 {
      display: block;

      .cell-tip {
        display: flex;
        justify-content: space-between;
        margin-top: 20rpx;
        align-items: center;

        .wallet {
          font-size: 28rpx;
          color: #ff6c18;
        }
      }
    }
  }

  .hjfScore {
    margin-top: 10rpx;
    text-align: left;
    color: #909399;
  }

  .radioBox {
    display: flex;
    justify-content: center;
    align-items: center;
    margin-top: 40rpx;

    :deep(.u-radio) {
      justify-content: center;
    }
  }

  .hy-btn {
    margin-top: 50rpx;
  }

  .hy-link {
    margin-top: 30rpx;
    text-align: right;
    color: #909399;
    text-decoration: underline;
  }
}

.inputBox {
  // 输入框样式
}
</style>